package com.derbysoft.synxisadapter.webservice.impl;

import com.derbysoft.synxisadapter.commons.dto.synxis.OtaRequestMessage;
import com.derbysoft.synxisadapter.commons.dto.synxis.OtaResponseMessage;
import com.derbysoft.synxisadapter.commons.log.LogDetailPair;
import com.derbysoft.synxisadapter.commons.log.TransactionLogger;
import com.derbysoft.synxisadapter.commons.model.Channel;
import com.derbysoft.synxisadapter.commons.model.Direction;
import com.derbysoft.synxisadapter.commons.utils.ErrorMessageUtils;
import com.derbysoft.synxisadapter.webservice.SynXisWebService;
import org.springframework.ws.client.core.WebServiceTemplate;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * User: jason
 * Date: 2012-12-05
 */
public abstract class AbstractReservationWebService<RQ extends OtaRequestMessage, RS extends OtaResponseMessage>
        extends AbstractSynXisWebService<RQ, RS> implements SynXisWebService<RQ, RS> {

    public RS invoke(RQ request, Channel channel) throws Exception {
        Set<LogDetailPair> logDetails = TransactionLogger.getLogDetails().get();
        if (logDetails == null) {
            logDetails = new HashSet<LogDetailPair>();
            TransactionLogger.getLogDetails().set(logDetails);
        }
        logDetails.add(LogDetailPair.build(request, Direction.TO_HOTEL));
        try {
            RS response = invoke(getWebServiceTemplate(), request, channel);
            logDetails.add(LogDetailPair.build(response, Direction.FROM_HOTEL));
            return response;
        } catch (Exception ex) {
            TransactionLogger.getTransactionLogger().get().setError(true);
            logDetails.add(LogDetailPair.build(ErrorMessageUtils.buildErrorMessage(ex), Direction.FROM_HOTEL));
            throw new Exception(ex);
        }
    }

    @Override
    public List<ResponsePair<RQ, RS>> batchInvoke(List<RQ> requests, Channel channel) throws Exception {
        Set<LogDetailPair> logDetails = TransactionLogger.getLogDetails().get();
        if (logDetails == null) {
            logDetails = new HashSet<LogDetailPair>();
            TransactionLogger.getLogDetails().set(logDetails);
        }
        for (RQ request : requests) {
            logDetails.add(LogDetailPair.build(request, Direction.TO_HOTEL));
        }
        try {
            List<ResponsePair<RQ, RS>> responsePairs = doBatchInvoke(getWebServiceTemplate(), requests, channel);
            for (ResponsePair<RQ, RS> responsePair : responsePairs) {
                logDetails.add(LogDetailPair.build(responsePair.getResponse(), Direction.FROM_HOTEL));
            }
            return responsePairs;
        } catch (Exception ex) {
            TransactionLogger.getTransactionLogger().get().setError(true);
            logDetails.add(LogDetailPair.build(ErrorMessageUtils.buildErrorMessage(ex), Direction.FROM_HOTEL));
            throw new Exception(ex);
        }
    }

    protected abstract WebServiceTemplate getWebServiceTemplate();
}
